package tomcat;

import tomcat.common.FileUtil;
import tomcat.socket.MySocketHandler;

import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import java.io.File;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
 * 自定义Tomcat
 */
public class MyTomcat {
    /**
     * URLMap
     */
    private final Map<String, HttpServlet> urlPatternMap = new HashMap<>();

    public static void main(String[] args) {
        MyTomcat myTomcat = new MyTomcat();
        //部署应用
        myTomcat.deployApp();
        //启动
        myTomcat.start();
    }

    /**
     * 启动方法，一直接收Socket，并放入线程池处理
     */
    private void start() {
        try {
            //构建监听服务，并绑定监听端口
            ServerSocket serverSocket = new ServerSocket(8080);
            while (true) {
                //获取客户端连接
                Socket socket = serverSocket.accept();
                //处理客户端连接
                MySocketHandler.handle(socket, urlPatternMap);
            }
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 部署应用
     */
    private void deployApp() {
        //获取根目录
        String rootDir = System.getProperty("user.dir");
        System.out.println("根目录：" + rootDir);
        File webapps = new File(rootDir, "webapps");
        for (String webapp : Objects.requireNonNull(webapps.list())) {
            File webappDir = new File(webapps, webapp);
            File classesDir = new File(webappDir, "classes");

            URLClassLoader urlClassLoader;
            try {
                URL fileURL = classesDir.toURI().toURL();
                System.out.println("文件URL：" + fileURL);
                //构建URL类加载器
                urlClassLoader = new URLClassLoader(new URL[]{fileURL});
            } catch (Exception e) {
                throw new RuntimeException(e);
            }

            List<File> files = FileUtil.getAllFile(classesDir);
            for (File clazz : files) {
                String path = clazz.getPath();
                System.out.println("path：" + path);
                String name = path.replace(classesDir.getPath() + "\\", "");
                System.out.println("name：" + name);
                name = name.replace(".class", "");
                System.out.println("name：" + name);
                name = name.replace("\\", ".");
                System.out.println("name：" + name);
                try {
                    //获取类
                    Class<?> servletClass = urlClassLoader.loadClass(name);
                    //判断是否是HttpServlet子类
                    if (HttpServlet.class.isAssignableFrom(servletClass)) {
                        //判断是否包含注解
                        if (servletClass.isAnnotationPresent(WebServlet.class)) {
                            //获取注解
                            WebServlet webServlet = servletClass.getAnnotation(WebServlet.class);
                            String[] urlPatterns = webServlet.urlPatterns();
                            for (String urlPattern : urlPatterns) {
                                //获取实现类对象
                                HttpServlet httpServlet = (HttpServlet) servletClass.getDeclaredConstructor().newInstance();
                                urlPatternMap.put(urlPattern, httpServlet);
                            }
                        }
                    }
                } catch (Exception e) {
                    throw new RuntimeException(e);
                }
            }
        }
    }
}